import React from 'react';
import { fullProvider,lazyInject } from 'legions-control-container';
import { inject } from 'legions/store'
import ProjectFormPropertyStore,{ ComponentType } from '../../stores/projectFormProperty';
import {
    PropertyInputVModel,
    PropertySelectVModel,
    PropertyDatePickerVModel,
    PropertyRangePickerVModel,
    PropertyUploadVModel,
    PropertySwitchVModel,
    PropertyRadioButtonVModel,
    PropertyRadioVModel
} from '../../models/propertyVModel';
import {
    action,computed
} from 'mobx';
import { filterFormProperty,FORMSUBMITPROPERTY,FORM_PROPERTY_DIFF_SET,I_FORM_PROPS } from '../../constants/consts';
import get from 'lodash/get';
import set from 'lodash/set';
import has from 'lodash/has';
import { MapperEntity } from 'json-mapper-object';
import { PropertyFormElementFormFields } from '../../models/form/propertyFormElement';
import { LegionsProForm } from 'legions-pro-design'
import ProjectStore from '../../stores/projectStore';
import { shortHash } from 'legions-lunar/object-hash';
import ProjectCommonStore from '../../stores/projectCommonStore';
import { randomNum } from '../../utils/utils';
import { LETTER } from '../../constants/table-config/table';
const FORM_BASE_DATA = {
    text: {
        name: '文本框',
    },
    select: {
        name: '下拉列表'
    },
    radioButton: {
        name: '单选按钮'
    },
    radio: {
        name: '单选'
    },
    date: {
        name: '日期',
    },
    daterange: {
        name: '日期范围',
    },
    upload: {
        name: '上传',
    },
    switch: {
        name: '开关',
    }
}
@fullProvider(FormCanvasDomain)
export class FormCanvasDomain {
    @inject(ProjectFormPropertyStore)
    formPropertyStore: ProjectFormPropertyStore;

    @inject(ProjectCommonStore)
    projectCommonApp: ProjectCommonStore;
    elementLabels = FORM_BASE_DATA;
    /** 随机生成组件id */
    private randomComponentId(type: string) {
        let name =`${type}A`
        const index = randomNum(0,LETTER.length - 1);
        if (index <= LETTER.length - 1) {
            name = `${type}${LETTER[index]}`
        }
        return name;
    } 
    renderFormLable(label: string,type: string,uid: string) {
        return <span onClick={this.onLabelClick.bind(this,type,uid,label)}>{label}</span>
    }
    onLabelClick(type: ComponentType,uid: string,label: string) {
        const formPropertyApp = this.formPropertyStore;
        const elementUidItem = formPropertyApp.propertyFormationVM.elementUidMaps.get(uid);
        formPropertyApp.propertyFormationVM.dispatchAction(() => {
            formPropertyApp.propertyFormationVM.editComponentData.keys = elementUidItem.uuid;
            formPropertyApp.propertyFormationVM.editComponentData.randomUid=uid,
            formPropertyApp.propertyFormationVM.editComponentData.type = type;
            /** 同步正在编辑的组件UID，用途比如存储下拉框数据 */
            this.projectCommonApp.modifyActivityComponentUid(elementUidItem.uuid);
        });
        formPropertyApp.formPropertyModalRef.viewModel.visible = true;
        formPropertyApp.formPropertyModalRef.viewModel.title = '设置表单元素属性';
        const forEachFormComponents = () => { /** 根据组件类型控制显示或隐藏的组件配置项 */
            const filterValue = filterFormProperty(type);
            const timeid = setTimeout(() => {
                filterValue.nonCurrentList.map((fvalue) => {
                    formPropertyApp.formProperyElementRef.methods.setFormStates(fvalue,(value) => {
                        value.iFormProps.visible = false;
                    })
                })
                filterValue.currentList.map((fvalue) => {
                    formPropertyApp.formProperyElementRef.methods.setFormStates(fvalue,(value) => {
                        value.iFormProps.visible = true;
                    });
                })
                clearTimeout(timeid)
            },50)
        }
        forEachFormComponents();
        const VModel = {
            text: PropertyInputVModel,
            select: PropertySelectVModel,
            date: PropertyDatePickerVModel,
            daterange: PropertyRangePickerVModel,
            upload: PropertyUploadVModel,
            switch: PropertySwitchVModel,
            radioButton: PropertyRadioButtonVModel,
            radio: PropertyRadioVModel,
        };
        let model = {};
        const propertyData = formPropertyApp.propertyFormationVM.propertyData
                     .get(elementUidItem.uuid)
         FORMSUBMITPROPERTY[type] &&
             FORMSUBMITPROPERTY[type].map(items => {
                 const itemValue = propertyData.propertyValue.find(item => item.key === items);
                 model[items] = get(itemValue,'value',void 0);
             });
        const oldFormItem = { ...formPropertyApp.formPropertyDraggerRef.viewModel.getFormItemField(elementUidItem.uuid)?.value };
        
         const values = MapperEntity(VModel[type],{
             ...oldFormItem,
             ...model,
         });
        values.label = elementUidItem.label;
        values.name = elementUidItem.name;
        const value = PropertyFormElementFormFields.dataToFormFields<
            PropertyFormElementFormFields,
            {}
            >(new PropertyFormElementFormFields(),values);
        const timeid = setTimeout(() => {
            if (formPropertyApp.formProperyElementRef) {
                formPropertyApp.formProperyElementRef.store.updateFormInputData(
                    formPropertyApp.formProperyElementRef.uid,
                    value,
                );
            }
            clearTimeout(timeid);
        },100);
    }
    createElementConfig(
        type: string,
        item: { componentName: string; label: string; uid: string }
    ) {
        const formUtils = new LegionsProForm.ProFormUtils<ProjectStore>({ store: ProjectStore });
        const labelElement = this.renderFormLable(item.label,type,item.uid)
        const span = 6;
        const wrapSpan = 18;
        switch (type) {
            case 'text':
                return formUtils.renderInputConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,''),
                    iFormProps: {
                        ...formUtils.createLayout(
                            labelElement,
                            span,
                            wrapSpan
                        ),
                        maxLength: '50',
                        type: 'text',
                    },
                    rules: [],
                });
            case 'select':
                return formUtils.renderSelectConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,''),
                    iFormProps: {
                        ...formUtils.createLayout(
                            labelElement,
                            span,
                            wrapSpan
                        ),
                        allowClear: true,
                        options: [],
                    },
                    rules: [],
                });
            case 'radioButton':
                return formUtils.renderRadioButtonConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,''),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                        radioButton: {
                            options: [
                                {
                                    label: '广州',
                                    value: 'guangzhou',
                                },
                                {
                                    label: '上海',
                                    value: 'shanghai',
                                },
                            ],
                        },
                    },
                    rules: [],
                });
            case 'radio':
                return formUtils.renderRadioButtonConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,''),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                        radio: {
                            options: [
                                { disabled: false,label: '是',value: '1' },
                                { disabled: false,label: '否',value: '0' },
                            ],
                        },
                    },
                    rules: [],
                });
            case 'date':
                return formUtils.renderDatePickerConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,'日期'),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                        format: 'YYYY-MM-DD HH:mm:ss',
                        showToday: true,
                        showTime: true,
                    },
                    rules: [],
                });
            case 'daterange':
                return formUtils.renderRangePickerConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,'日期'),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                        format: 'YYYY-MM-DD HH:mm:ss',
                        showTime: true,
                    },
                    rules: [],
                });
            case 'upload':
                return formUtils.renderUploadConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,'上传'),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                    },
                    rules: [],
                });
            case 'switch':
                return formUtils.renderSwitchConfig({
                    iAntdProps: formUtils.createAntdProps(item.componentName,1,'开关'),
                    iFormProps: {
                        ...formUtils.createLayout(
                            this.renderFormLable(item.label,type,item.uid),
                            span,
                            wrapSpan
                        ),
                    },
                    rules: [],
                });
        }
    }
    /** 单击左侧可添加表单元素信息，添加表单元素组件
     *  UI单击事件
     */
    addFormElement(componentType: string) {
        const baseData = FORM_BASE_DATA[componentType]
        const uid = `${shortHash(componentType + new Date().getTime())}`;
        const name = `element${this.formPropertyStore.propertyFormationVM.propertyData.size}`;
        const label = baseData && baseData.name
        const component = this.createElementConfig(componentType as string,{
            componentName: name,
            label: label,
            uid,
        })
        this.formPropertyStore.propertyFormationVM.elementUidMaps.set(uid,{
            uid,
            uuid: component.iAntdProps.uuid,
            label,
            name,
        })
        const timeid = setTimeout(() => {
            this.formPropertyStore.formPropertyDraggerRef.methods.addFormItem([component]);
            clearTimeout(timeid);
        },50);
        this.formPropertyStore.addFormElement(component.iAntdProps.uuid,label,componentType as ComponentType)
    }
    /** 同步更新表单元素组件属性 */
    asyncElementData(formFields: PropertyFormElementFormFields) {
        const store = this.formPropertyStore;
        
        const randomUid = store.propertyFormationVM.editComponentData.randomUid;
        const type = store.propertyFormationVM.editComponentData.type;
        /* const item = store.propertyFormationVM.compoentData.get(keys); */
        const item = store.formPropertyDraggerRef.viewModel.getFormItemField(store.propertyFormationVM.editComponentData.keys).value;
        const uuid = item.iAntdProps['uuid'];

        const iAntdProps = store.updateIAntdProps(formFields);
        const inputPorps = store.updateInputElementProps(formFields,uuid);
        const selectProps = store.updateSelectElementProps(formFields,uuid);
        const uploadProps = store.updateUploadElementProps(formFields,uuid);
        const radioProps = store.updateRadioElementProps(formFields,uuid);
        const dataProps = store.updateDateElementProps(formFields,uuid);
        const {
            //@ts-ignore
            ...iformProps } = store.updateCommonElementProps(
                formFields,
                uuid
            );
        let formProps = {};
        const { label,...oldiFormProps } = item['iFormProps'];
        formProps = {
            ...oldiFormProps,
            ...iformProps,
            ...inputPorps,
            ...selectProps,
            ...uploadProps,
            ...dataProps,
            ...radioProps,
        };
        const elementUidMapsItem = store.propertyFormationVM.elementUidMaps.get(randomUid);
        /** 同步数据状态回表单拖拽生成区域 */
        store.formPropertyDraggerRef.methods.setFormStates(item.iAntdProps.id,(value) => {
            const {
                //@ts-ignore
                label,
                ...prop } = formProps;
            if (label) {
                value.iFormProps.label = this.renderFormLable(label,type,randomUid);
                if (elementUidMapsItem&&typeof label==='string') {
                    elementUidMapsItem.label = label;
                    store.propertyFormationVM.elementUidMaps.set(randomUid,elementUidMapsItem)
                }
            }
            //@ts-ignore
            const { id,name,...props } = iAntdProps;
            if (name&&elementUidMapsItem) {
                elementUidMapsItem.name = name;
                store.propertyFormationVM.elementUidMaps.set(randomUid,elementUidMapsItem)
            }
            value.iAntdProps = {
                ...value.iAntdProps,
                ...props,
            }
            value.iFormProps = {
                ...value.iFormProps,
                ...prop,
            };
            value.rules = store.updateRulesRequired(formFields,item.rules)
        })
    }
}